package com.blood.modules.system.service.impl;

import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blood.core.config.mybatisplus.ICommonServiceImpl;
import com.blood.core.enums.StatusEnum;
import com.blood.core.resp.GlobalResultStatus;
import com.blood.core.resp.PageResult;
import com.blood.core.resp.ResponseResult;
import com.blood.core.util.ObjectAssertUtil;
import com.blood.core.util.bean.BeanUtil;
import com.blood.core.util.bean.BeanUtils;
import com.blood.core.util.http.RequestTheadUtils;
import com.blood.modules.system.dto.req.SysOrgSchemaPageReq;
import com.blood.modules.system.dto.req.SysOrgSchemaReq;
import com.blood.modules.system.dto.req.SysOrgSchemaSaveReq;
import com.blood.modules.system.dto.resp.SysOrgSchemaInfoResp;
import com.blood.modules.system.dto.resp.SysOrgSchemaPageResp;
import com.blood.modules.system.mapper.SysOrgSchemaMapper;
import com.blood.modules.system.mapper.SysUserMapper;
import com.blood.modules.system.model.SysOrgSchema;
import com.blood.modules.system.model.SysUser;
import com.blood.modules.system.service.ISysOrgSchemaService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 组织架构Service业务层处理
 *
 * @author daoren
 * @date 2022-05-12 09:14:45
 */
@Service
public class SysOrgSchemaServiceImpl extends ICommonServiceImpl<SysOrgSchemaMapper, SysOrgSchema> implements ISysOrgSchemaService {
    @Autowired
    private Snowflake snowFlake;
    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public ResponseResult<PageResult<SysOrgSchemaPageResp>> pageList(SysOrgSchemaPageReq req) {
        PageResult<SysOrgSchemaPageResp> pageResult = PageResult.create(req.getPageNo(), req.getPageSize());
        LambdaQueryWrapper<SysOrgSchema> qw = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(req.getParentId())) {
            qw.eq(SysOrgSchema::getParentId, req.getParentId());
        }
        if (StringUtils.isNotBlank(req.getAddress())) {
            qw.like(SysOrgSchema::getAddress, req.getAddress());
        }
        if (StringUtils.isNotBlank(req.getContact())) {
            qw.like(SysOrgSchema::getContact, req.getContact());
        }
        if (StringUtils.isNotBlank(req.getHead())) {
            qw.like(SysOrgSchema::getHead, req.getHead());
        }
        if (null != req.getStatus()) {
            qw.eq(SysOrgSchema::getStatus, req.getStatus());
        }
        qw.eq(SysOrgSchema::isDeleteFlag, false);
        qw.orderByDesc(SysOrgSchema::getCreateTime);

        IPage<SysOrgSchema> iPage = baseMapper.selectPage(new Page<>(req.getPageNo(), req.getPageSize()), qw);
        if (iPage.getRecords().size() > 0) {
            ArrayList<SysOrgSchemaPageResp> respList = new ArrayList<>();
            List<SysOrgSchema> parentInfo = queryList(iPage.getRecords().stream().filter(f->!"0".equals(f.getParentId())).map(m -> m.getParentId()).collect(Collectors.toList()));
            for (SysOrgSchema record : iPage.getRecords()) {
                SysOrgSchemaPageResp resp = BeanUtils.copyProperties(record, SysOrgSchemaPageResp.class);
                if (!"0".equals(resp.getParentId())) {
                    resp.setHospitalName(parentInfo.stream().filter(f -> f.getId().equals(record.getParentId()))
                            .findFirst().orElse(new SysOrgSchema()).getHospitalName());
                }
                respList.add(resp);
            }
            return GlobalResultStatus.SUCCESS.toResult().response(pageResult.data(iPage.getTotal(), respList));
        }
        return GlobalResultStatus.SUCCESS.toResult().response(pageResult.data(0, Collections.emptyList()));
    }

    @Override
    public List<SysOrgSchema> queryList(SysOrgSchemaReq req) {
        return baseMapper.selectList(new QueryWrapper<SysOrgSchema>()
                .lambda()
                .eq(SysOrgSchema::getStatus, StatusEnum.ENABLE.getValue())
                .eq(SysOrgSchema::getParentId, req.getParentId())
                .eq(SysOrgSchema::isDeleteFlag, false));
    }

    @Override
    public List<SysOrgSchema> queryList(List<String> idList) {
        if(idList.size()>0){
            return baseMapper.selectList(new QueryWrapper<SysOrgSchema>()
                    .lambda()
                    .in(SysOrgSchema::getId, idList)
                    .eq(SysOrgSchema::isDeleteFlag, false));
        }
        return Collections.emptyList();

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> saveInfo(SysOrgSchemaSaveReq req) {
        String id = snowFlake.nextIdStr();
        SysOrgSchema saveInfo = new SysOrgSchema();
        BeanUtil.copyProperties(req, saveInfo);
        saveInfo.setId(id);
        saveInfo.setCreateBy(RequestTheadUtils.getUserId());
        baseMapper.insert(saveInfo);
        return GlobalResultStatus.SUCCESS.toResult().responseEmptyBody();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateInfo(SysOrgSchemaSaveReq req) {
        SysOrgSchema queryInfo = super.findById(req.getId());
        ObjectAssertUtil.objectIsNull(queryInfo, "未获取到详细信息!");
        BeanUtil.copyProperties(req, queryInfo);
        queryInfo.setUpdateBy(RequestTheadUtils.getUserId());
        baseMapper.updateById(queryInfo);
        return GlobalResultStatus.SUCCESS.toResult().responseEmptyBody();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateStatus(String id) {
        SysOrgSchema queryInfo = super.findById(id);
        ObjectAssertUtil.objectIsNull(queryInfo, "未获取到详细信息!");
        SysOrgSchema updateInfo = new SysOrgSchema();
        updateInfo.setLineNo(queryInfo.getLineNo());
        updateInfo.setStatus(StatusEnum.ENABLE.getValue().equals(queryInfo.getStatus()) ? StatusEnum.DIS_ENABLE.getValue() : StatusEnum.ENABLE.getValue());
        updateInfo.setUpdateBy(RequestTheadUtils.getUserId());
        baseMapper.updateById(updateInfo);
        return GlobalResultStatus.SUCCESS.toResult().responseEmptyBody();
    }

    @Override
    public ResponseResult<SysOrgSchemaInfoResp> findDetailById(String id) {
        SysOrgSchema queryInfo = super.findById(id);
        ObjectAssertUtil.objectIsNull(queryInfo, "详细信息不存在!");
        return GlobalResultStatus.SUCCESS.toResult().response(BeanUtil.copyProperties(queryInfo, SysOrgSchemaInfoResp.class));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> deleted(String id) {
        SysOrgSchema queryInfo = super.findById(id);
        ObjectAssertUtil.objectIsNull(queryInfo, "信息已删除，不可重复删除!");
        //根级查是否存在子集
        if ("0".equals(queryInfo.getParentId())) {
            List<SysOrgSchema> schemaList = getSysOrgSchemas(queryInfo.getId());
            ObjectAssertUtil.isBoolean(schemaList.size() > 0, "该医院存在关联科室，不可删除！");
        } else {
            //子集查是否管理用户
            SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getDepartId, queryInfo.getId())
                    .eq(SysUser::isDeleteFlag, false)
                    .last("limit 1"));
            ObjectAssertUtil.objectIsNotNull(sysUser, "该科室存在关联用户，不可删除！");
        }
        removeById(queryInfo.getLineNo());
        return GlobalResultStatus.SUCCESS.toResult().responseEmptyBody();
    }

    @Override
    public List<String> queryMyOrSubList(String orgId) {
        List<SysOrgSchema> orgSchemaList = getSysOrgSchemas(orgId);
        List<String> orgIdList = orgSchemaList.stream().map(m -> m.getId()).collect(Collectors.toList());
        orgIdList.add(orgId);
        return orgIdList;
    }

    private List<SysOrgSchema> getSysOrgSchemas(String orgId) {
        List<SysOrgSchema> orgSchemaList = baseMapper.selectList(new QueryWrapper<SysOrgSchema>()
                .lambda()
                .eq(SysOrgSchema::getParentId, orgId)
                .eq(SysOrgSchema::isDeleteFlag, false));
        return orgSchemaList;
    }
}
